
#ifndef _DRV_SER_H
#define _DRV_SER_H

#ifdef __cplusplus
extern "C" {
#endif

#include "sal.h"

#define DRV_MEM_ADD0(lchip, mem_id)                 (DRV_MEM_INFO(lchip, mem_id).addr_3w)
#define DRV_MEM_TCAM_ID(lchip, mem_id)              (DRV_MEM_INFO(lchip, mem_id).tcam_map_id)

enum drv_ser_action_e
{
    DRV_SER_ACTION_NULL       = 0,
    DRV_SER_ACTION_LOG,
    DRV_SER_ACTION_RESET_CHIP,
    DRV_SER_ACTION_RESET_PORT
};
typedef enum drv_ser_action_e drv_ser_action_t;

enum drv_ser_type_e
{
   DRV_SER_TYPE_SBE,
   DRV_SER_TYPE_MBE,
   DRV_SER_TYPE_PARITY_ERROR,
   DRV_SER_TYPE_TCAM_ERROR,
   DRV_SER_TYPE_OTHER,
   DRV_SER_TYPE_NUM
};
typedef enum drv_ser_type_e drv_ser_type_t;

typedef int32 (* drv_ser_event_fn)(uint8 gchip, void* p_data);

struct drv_ser_cb_info_s
{
   uint8  type;  /*drv_ser_type_t*/
   uint32 tbl_id;
   uint32 tbl_index;
   uint8  action;   /*drv_ser_action_t*/
   uint8  recover;
   void* intr_type;
};
typedef struct drv_ser_cb_info_s drv_ser_cb_info_t;

enum drv_ser_cfg_type_e
{
    DRV_SER_CFG_TYPE_SCAN_MODE,
    DRV_SER_CFG_TYPE_TCAM_SCAN_INFO,
    DRV_SER_CFG_TYPE_ECC_INTERRUPT_INFO,
    DRV_SER_CFG_TYPE_HW_RESER_EN,
    DRV_SER_CFG_TYPE_SHOW_SER_STAUTS,
    DRV_SER_CFG_TYPE_ECC_EVENT_CB,
    DRV_SER_CFG_TYPE_DMA_RECOVER_TCAM
};
typedef enum drv_ser_cfg_type_e drv_ser_cfg_type_t;

enum drv_ser_scan_type_e
{
    DRV_SER_SCAN_TYPE_TCAM,
    DRV_SER_SCAN_TYPE_SBE,
    DRV_SER_SCAN_TYPE_NUM
};
typedef enum drv_ser_scan_type_e drv_ser_scan_type_t;

enum drv_ser_hw_reset_cb_tyep_e
{
    DRV_SER_HW_RESET_CB_TYPE_DATAPATH,
    DRV_SER_HW_RESET_CB_TYPE_REGISTER,
    DRV_SER_HW_RESET_CB_TYPE_INTERRUPT,
    DRV_SER_HW_RESET_CB_TYPE_DMA,
    DRV_SER_HW_RESET_CB_TYPE_OAM,
    DRV_SER_HW_RESET_CB_TYPE_FDB,
    DRV_SER_HW_RESET_CB_TYPE_MAC,
    DRV_SER_HW_RESET_CB_TYPE_EUNIT,
    DRV_SER_HW_RESET_CB_TYPE_DMA_CLEAR,     /*Before reset switch core for disable dma channel*/
    DRV_SER_HW_RESET_CB_TYPE_PTP,
    DRV_SER_HW_RESET_CB_TYPE_NUM
};
typedef enum drv_ser_hw_reset_cb_tyep_e drv_ser_hw_reset_cb_tyep_t;

/* tcam/sbe scan param*/
struct drv_ser_scan_info_s
{
    drv_ser_scan_type_t type;
    uint8     mode;
    uint32   scan_interval;
    uint32   burst_entry_num;
    uint32   burst_interval;
};
typedef struct drv_ser_scan_info_s drv_ser_scan_info_t;

struct drv_ser_dma_tcam_param_s
{
    uint16 mem_id;
    uint16 sub_mem_id;
    uint32 entry_size;
    uint32 time_stamp[2];   /*for AT, time_stamp[0] is error address, time_stamp[1] is opbmp[7:0] (core_bmp[7:6] + pp_bmp[5:2] + dp_bmp[1:0])*/
    uint32* p_memory;
};
typedef struct drv_ser_dma_tcam_param_s drv_ser_dma_tcam_param_t;

struct drv_ecc_sbe_cnt_s
{
    uint32 tblid     :16;
    uint32 rec       :16;
    uint32    fld    : 16;
    uint32  index    :4;
    uint32  old_value : 4;
    uint32  rsv      :8;
};
typedef struct drv_ecc_sbe_cnt_s drv_ecc_sbe_cnt_t;


struct drv_ecc_data_s
{
        drv_ecc_sbe_cnt_t*  p_sbe_cnt;
        drv_ecc_intr_tbl_t* p_intr_tbl;
        uint16 (*p_scan_tcam_tbl)[5];
};
typedef struct drv_ecc_data_s drv_ecc_data_t;

struct drv_ser_global_cfg_s
{
    uint32  tcam_scan_en     :1;        /**< enable tcam scan */
    uint32  sbe_scan_en      :1;        /**< enable single bit error scan */
    uint32  ecc_recover_en   :1;        /**< enable ecc/parity error recover */
    uint32  sdb_en           :1;        /**< overall control */
    uint32  sdb_type         :3;
    uint32  rsv              :26;

    uintptr mem_addr;                     /**<  the start memory address of SDB */
    uint32  mem_size;                     /**<  the memory size of SDB */
    uint32  tcam_scan_burst_entry_num;  /**< tcam key scan entries num per burst */
    uint32  tcam_scan_interval;         /**< tcam key scan all time interval, unit is ms */
    uint32  sbe_scan_interval;          /**< single bit error scan all time interval, unit is ms */
    uint64  cpu_mask;
};
typedef struct drv_ser_global_cfg_s drv_ser_global_cfg_t;

struct drv_ser_scan_thread_s
{
    uint16      prio;
    sal_task_t* p_scan_task;
};
typedef struct drv_ser_scan_thread_s drv_ser_scan_thread_t;

struct drv_ser_master_s
{
    uint32                 recover_static_cnt;
    uint32                 recover_dynamic_cnt;
    uint32                 recover_tcam_key;
    uint32                 recover_sbe_cnt;
    uint32                 ignore_cnt;

    drv_ser_event_fn       ser_event_cb;
    uint32                 sbe_scan_en    :1;
    uint32                 tcam_scan_en   :1;
    uint32                 ecc_recover_en :1;
    uint32                 remove_free_tcam_en :1; /**< if set,will remove free tcam entry in a scan period  */
    uint32                 simulation_en :1;
    uint32                 err_rec_offset :18;     /*if simulation_en set 1, ECC table pointer to err_rec_offset */
    uint32                 rsv :8;

    uint32                 tcam_scan_burst_interval;             /* unit is ms */
    uint32                 tcam_scan_burst_entry_num;            /* acl/scl/ip unit is 160bit, nat/pbr unit is 40bit */
    uint32                 scan_interval[DRV_SER_SCAN_TYPE_NUM]; /* unit is ms, 0 means disable scan thread*/
    uint8                  scan_doing[DRV_SER_SCAN_TYPE_NUM];
    drv_ser_scan_thread_t  scan_thread[DRV_SER_SCAN_TYPE_NUM];
};
typedef struct drv_ser_master_s drv_ser_master_t;

typedef int32 (* drv_ser_hw_reset_cb)(uint8 lchip, void* p_data);
typedef int32 (* drv_ser_get_data_memory_cb)(uint8 lchip, uint8 chan_id, uint32 cur_index, uint32 mem_id, uint32* cfg_size, uint32 **pp_desc_addr, uint32 **pp_logic_addr);

extern int32
drv_ser_init(uint8 lchip ,drv_ser_global_cfg_t* p_cfg);
extern int32
drv_ser_deinit(uint8 lchip );

extern int32
drv_ser_register_hw_reset_cb(uint8 lchip ,uint32 cb_type,drv_ser_hw_reset_cb cb);
extern int32
drv_ser_restore(uint8 lchip, drv_ecc_intr_param_t* p_intr_param);
extern int32
drv_ser_set_cfg(uint8 lchip, uint32 type, void* p_cfg);
extern int32
drv_ser_get_cfg(uint8 lchip, uint32 type, void* p_cfg);
#if defined(EMULATION_ENV) && !defined(EMULATOR_ENV)
extern int32
drv_ser_set_entry_bitmap(uint8 lchip, uint32 mem_id, uint32 entry_idx, uint8 enable, uint8 need_cal_hash, void* test_data);
#else
extern int32
drv_ser_set_entry_bitmap(uint8 lchip, uint32 mem_id, uint32 entry_idx, uint8 oper_bmp);
#endif
extern int32
drv_ser_register_dma_data_memory_cb(uint8 lchip, drv_ser_get_data_memory_cb func);


extern int32
drv_ser_mem_check(uint8 lchip, uint8 mem_id, uint8 recover_en, uint8* cmp_result);
extern void
drv_ser_get_master_info(uint8 lchip, uint8* ecc_recover_en);
extern void
drv_ser_report_ser_event_cb(uint8 lchip, drv_ser_cb_info_t* p_ecc_cb);

#ifdef __cplusplus
}
#endif

#endif


